﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel;

public class ExcelFile
{
    //是否文件解析失败
    public bool IsError { get { return m_isError; } }
    //文件名
    public string FileName { get { return m_fileName; } }
    //数据类型
    public Dictionary<int, string> TypeDic { get { return m_typeDic; } }
    //导出类型
    public Dictionary<int, string> ExportTypeDic { get { return m_exportTypeDic; } }
    //数据属性名
    public Dictionary<int, string> PropNameDic { get { return m_propNameDic; } }
    //数据注释
    public Dictionary<int, string> NotesDic { get { return m_notesDic; } }

    //保存客户器数据
    public void SaveClientData(string path)
    {
        if(!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        string filePath = path + "/" + FileName + ".bytes";
        FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate);
        byte[] bytes = m_clientBuffer.ToBytes();
        fs.Write(bytes, 0, bytes.Length);
        fs.Close();
    }

    //保存服务端数据
    public void SaveServerData(string path)
    {
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        string filePath = path + "/" + FileName + ".bytes";
        FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate);
        byte[] bytes = m_serverBuffer.ToBytes();
        fs.Write(bytes, 0, bytes.Length);
        fs.Close();
    }

    //分析表格数据
    public ExcelFile(string path)
    {
        if (File.Exists(path))
        {
            m_fileName = Path.GetFileNameWithoutExtension(path);
            FileStream mStream = File.Open(path, FileMode.Open, FileAccess.Read);
            IExcelDataReader mExcelReader = ExcelReaderFactory.CreateOpenXmlReader(mStream);
            DataSet mResultSet = mExcelReader.AsDataSet();
            mStream.Close();
            if (mResultSet.Tables.Count < 1)
            {
                m_errorCode = "找不到表格!";
                m_isError = true;
                return;
            }

            m_currentDataTable = mResultSet.Tables[0];
            if (m_currentDataTable.Rows.Count < 5)
            {
                m_errorCode = "表格数据错误!";
                m_isError = true;
                return;
            }

            rowCount = m_currentDataTable.Rows.Count;
            colCount = m_currentDataTable.Columns.Count;

            RefreshConfig();

            m_clientBuffer = new ByteBuffer();
            m_serverBuffer = new ByteBuffer();

            int dataCount = rowCount - 4;
            m_serverBuffer.WriteInt16((Int16)dataCount);
            m_clientBuffer.WriteInt16((Int16)dataCount);

            for (int i = 4; i < rowCount; i++)
            {
                for (int j = 0; j < colCount; j++)
                {
                    WriteClient(j, m_currentDataTable.Rows[i][j].ToString());
                    WriteServer(j, m_currentDataTable.Rows[i][j].ToString());
                }
            }
        }
        else
        {
            m_errorCode = "表格数据错误!";
            m_isError = true;
        }
    }

    //更新配置
    private void RefreshConfig()
    {
        m_notesDic.Clear();
        m_typeDic.Clear();
        m_exportTypeDic.Clear();
        m_propNameDic.Clear();

        for (int i = 0; i < colCount; i++)
        {
            string value = m_currentDataTable.Rows[0][i].ToString();
            m_notesDic.Add(i, value);

            value = m_currentDataTable.Rows[1][i].ToString();
            m_typeDic.Add(i, value);

            value = m_currentDataTable.Rows[2][i].ToString();
            m_exportTypeDic.Add(i, value);

            value = m_currentDataTable.Rows[3][i].ToString();
            m_propNameDic.Add(i, value);
        }
    }

    //写入客户端数据
    private bool WriteClient(int colIndex,string data)
    {
        if (m_typeDic.ContainsKey(colIndex))
        {
            string type = m_typeDic[colIndex];
            string writeType = m_exportTypeDic[colIndex];
            if(string.IsNullOrEmpty(writeType) || writeType == "CLIENT" || writeType == "ALL")
            {
                switch (type)
                {
                    case "STRING":
                        return WriteString(data, m_clientBuffer);
                    case "BYTE":
                        return WriteByte(data, m_clientBuffer);
                    case "INT16":
                        return WriteInt16(data, m_clientBuffer);
                    case "INT32":
                        return WriteInt32(data, m_clientBuffer);
                    case "INT64":
                        return WriteInt64(data, m_clientBuffer);
                    case "FLOAT":
                        return WriteFloat(data, m_clientBuffer);
                    default:
                        m_errorCode = "找不到类型";
                        return false;
                }
            }
        }
        return false;
    }

    //写入服务端数据
    private bool WriteServer(int colIndex, string data)
    {
        if (m_typeDic.ContainsKey(colIndex))
        {
            string type = m_typeDic[colIndex];
            string writeType = m_exportTypeDic[colIndex];
            if (string.IsNullOrEmpty(writeType) || writeType == "SERVER" || writeType == "ALL")
            {
                switch (type)
                {
                    case "STRING":
                        return WriteString(data, m_serverBuffer);
                    case "BYTE":
                        return WriteByte(data, m_serverBuffer);
                    case "INT16":
                        return WriteInt16(data, m_serverBuffer);
                    case "INT32":
                        return WriteInt32(data, m_serverBuffer);
                    case "INT64":
                        return WriteInt64(data, m_serverBuffer);
                    case "FLOAT":
                        return WriteFloat(data, m_serverBuffer);
                    default:
                        m_errorCode = "找不到类型";
                        return false;
                }
            }
        }
        return false;
    }

    private bool WriteString(string data,ByteBuffer byteBuffer)
    {
        byteBuffer.WriteString(data.ToString());
        return true;
    }

    private bool WriteByte(string data, ByteBuffer byteBuffer)
    {
        byte byteValue = 0;
        if (byte.TryParse(data, out byteValue))
        {
            byteBuffer.WriteByte(byteValue);
            return true;
        }
        else
        {
            byteBuffer.WriteByte(0);
            return false;
        }
    }

    private bool WriteInt16(string data, ByteBuffer byteBuffer)
    {
        Int16 byteValue = 0;
        if (Int16.TryParse(data, out byteValue))
        {
            byteBuffer.WriteInt16(byteValue);
            return true;
        }
        else
        {
            byteBuffer.WriteInt32(0);
            return false;
        }
    }

    private bool WriteInt32(string data, ByteBuffer byteBuffer)
    {
        Int32 byteValue = 0;
        if (Int32.TryParse(data, out byteValue))
        {
            byteBuffer.WriteInt32(byteValue);
            return true;
        }
        else
        {
            byteBuffer.WriteInt32(0);
            return false;
        }
    }

    private bool WriteInt64(string data, ByteBuffer byteBuffer)
    {
        Int64 byteValue = 0;
        if (Int64.TryParse(data, out byteValue))
        {
            byteBuffer.WriteInt64(byteValue);
            return true;
        }
        else
        {
            byteBuffer.WriteInt64(0);
            return false;
        }
    }

    private bool WriteFloat(string data, ByteBuffer byteBuffer)
    {
        float byteValue = 0;
        if (float.TryParse(data, out byteValue))
        {
            byteBuffer.WriteFloat(byteValue);
            return true;
        }
        else
        {
            byteBuffer.WriteFloat(0);
            return false;
        }
    }

    private int rowCount = 0;
    private int colCount = 0;
    private string m_fileName = string.Empty;
    private DataTable m_currentDataTable = null;
    private Dictionary<int, string> m_notesDic = new Dictionary<int, string>();
    private Dictionary<int, string> m_typeDic = new Dictionary<int, string>();
    private Dictionary<int, string> m_exportTypeDic = new Dictionary<int, string>();
    private Dictionary<int, string> m_propNameDic = new Dictionary<int, string>();
    private ByteBuffer m_clientBuffer = new ByteBuffer();
    private ByteBuffer m_serverBuffer = new ByteBuffer();
    private bool m_isError = false;
    private string m_errorCode = string.Empty;

}
